<template>
  <div class="container">
    <n-page-header title="话题详情" @back="toBack">
      <template #extra v-if="userStore.profile.id != null &&
      userStore.profile.id === topicData?.user_id &&
      topicData.status === 0">
        <n-button size="small" @click="closeTopic">关闭话题</n-button>
      </template>
    </n-page-header>

    <div class="author-info" v-if="userProfile != null">
      <n-card :bordered="false" embedded>
        <div>
          <n-thing>
            <template #header>
              作者信息
            </template>
            <template #header-extra v-if="userProfile.consult_price != null">
              <n-button type="primary" size="small" @click="consult">咨询</n-button>
            </template>
            <template #description>
              <n-p>{{userProfile.intro ?? '作者还没有发布个人介绍'}}</n-p>
            </template>
            <template #footer>
              <n-p depth="3" v-if="userProfile.consult_price != null">
                咨询价格：{{userProfile.consult_price}}金币 / 次
              </n-p>
              <n-p v-else>
                作者未开启咨询功能
              </n-p>
            </template>
          </n-thing>
        </div>
      </n-card>
    </div>

    <div class="content">
      <n-h4 prefix="bar">{{topicData?.title}}</n-h4>
      <n-p>
        {{topicData?.content}}
      </n-p>
      <n-p style="text-align: end" depth="3">{{topicData?.date}}</n-p>
    </div>

    <div class="message-list">
      <n-h4 prefix="bar">话题留言</n-h4>
      <n-space vertical v-if="topicData?.status === 0">
        <n-input v-model:value="messageInput" placeholder="在这里输入留言" type="textarea" maxlength="300" show-count />
        <n-button type="primary"
                  @click="createMessage"
                  :loading="createMessageRequesting"
                  :disabled="createMessageRequesting"
        >
          发表
        </n-button>
      </n-space>
      <div v-else-if="topicData?.status === 1" style="display: flex; align-items: center; justify-content: center">
        <n-p depth="3">该话题已关闭，无法留言</n-p>
      </div>
      <n-list>
        <n-list-item v-for="item in messageList" :key="item.id" :ref="setMessageItemRef">
          <n-thing>
            <template #description>
              <n-p>{{item.content}}</n-p>
            </template>

            <template #footer>
              <n-p depth="3">{{item.date}}</n-p>
            </template>
          </n-thing>
        </n-list-item>
      </n-list>
      <div class="fetch-message-status" style="display: flex; align-items: center; justify-content: center">
        <n-spin :size="18" v-if="fetchMessageRequesting" />
        <n-p depth="3" v-if="messageListNoMore">
          到底了，没有更多留言了
        </n-p>
      </div>
    </div>
  </div>
</template>

<script setup>
import {useRoute, useRouter} from "vue-router";
import {ref, nextTick} from "vue";
import {useRequests} from "@/common/requests.js";
import {useDialog, useMessage, useNotification} from "naive-ui";
import {useUserStore} from "@/stores/user.js";
import {useIntersectionObserver} from "@vueuse/core";

const route = useRoute()
const router = useRouter()
const requests = useRequests()

const dialog = useDialog()
const message = useMessage()
const notify = useNotification()
const userStore = useUserStore()

const toBack = () => {
  router.back()
}

const topicData = ref(null)
const userProfile = ref(null)

const requesting = ref(false)
const fetchTopic = () => {
  requesting.value = true
  requests.topic.detail(route.params.id).then(resp => {
    requesting.value = false
    if (resp.ret === 0) {
      topicData.value = resp.data

      fetchProfile(resp.data.user_id)
    } else {
      message.error(resp?.data ?? resp?.msg ?? '未知错误')
    }
  }).catch(err => {
    requesting.value = false

    console.log(err)
    notify.error({content: '出错了', meta: err.toString(), duration: 1500})
  })
}

const fetchProfile = id => {
  requests.profile.getById(id).then(resp => {
    if (resp.ret == 0) {
      userProfile.value = resp.data
    } else {
      message.error(resp?.data ?? resp?.msg ?? '未知错误')
    }
  }).catch(err => {
    console.log(err)
    notify.error({content: '出错了', meta: err.toString(), duration: 1500})
  })
}

const messageList = ref([])
const messageItemRef = ref([])
const setMessageItemRef = el => {
  messageItemRef.value.push(el)
}

const messagePage = ref({
  page: 0,
  offset: 20
})
const fetchMessageRequesting = ref(false)
const messageListNoMore = ref(false)
const fetchMessage = refresh => {
  if (fetchMessageRequesting.value) {
    return false
  }
  fetchMessageRequesting.value = true

  if (refresh) {
    messageItemRef.value = []
    messagePage.value.page = 0
    messageListNoMore.value = false
  }

  messagePage.value.page ++
  requests.message.listByTopic({topic_id: route.params.id, page: messagePage.value}).then(resp => {
    fetchMessageRequesting.value = false
    if (resp.ret === 0) {
      if (refresh) {
        messageList.value = resp.data
      } else {
        messageList.value.push(...resp.data)
      }

      if (resp.data.length < messagePage.value.offset) {
        messageListNoMore.value = true
      } else {
        nextTick(() => {
          const item = messageItemRef.value[messageItemRef.value.length - 2]
          const { stop } = useIntersectionObserver(item, ([{ isIntersecting }]) => {
            if (isIntersecting) {
              stop()
              fetchTopicList()
            }
          })
        })
      }
    } else {
      message.error(resp?.data ?? resp?.msg ?? '未知错误')
    }
  }).catch(err => {
    fetchMessageRequesting.value = false

    console.log(err)
    notify.error({content: '出错了', meta: err.toString(), duration: 1500})
  })
}

const messageInput = ref(null)
const createMessageRequesting = ref(null)
const createMessage = () => {
  if (messageInput.value == null || messageInput.value.length == 0) {
    message.error("请输入留言")
  } else {
    createMessageRequesting.value = true
    requests.message.new({
      topic_id: route.params.id,
      type: 0,
      content: messageInput.value
    }).then(resp => {
      createMessageRequesting.value = false
      if (resp.ret === 0) {
        fetchMessage(true)
        messageInput.value = null
        message.success("留言成功")
      } else {
        message.error(resp?.data ?? resp?.msg ?? "未知错误")
      }
    }).catch(err => {
      createMessageRequesting.value = false

      console.log(err)
      notify.error({content: "出错了", meta: err.toString(), duration: 1500})
    })
  }
}

const consult = () => {
  if (userProfile?.value?.id != null && userProfile?.value?.id === userStore.profile?.id) {
    message.error("不能咨询自己")
  } else {
    router.push({name: 'CreateConsultMessage', params: {user_id: userProfile?.value?.id}})
  }
}

const closeRequesting = ref(false)
const closeTopic = () => {
  dialog.create({
    closable: false,
    showIcon: null,
    title: '确定要关闭话题吗？',
    content: '关闭话题后将无法继续留言，且无法重新开启',
    positiveText: '继续关闭',
    negativeText: '取消',
    onPositiveClick: () => {
      closeRequesting.value = true
      requests.topic.close({id: route.params.id}).then(resp => {
        closeRequesting.value = false
        if (resp.ret === 0) {
          topicData.value.status = 1
          message.success("关闭成功")
        } else {
          message.error(resp?.data ?? resp?.msg ?? "未知错误")
        }
      }).catch(err => {
        closeRequesting.value = false

        console.log(err)
        notify.error({content: "出错了", meta: err.toString(), duration: 1500})
      })
    }
  })
}

fetchTopic()
fetchMessage()
</script>

<style lang="scss" scoped>
.container {
  .content {
    margin-top: 1rem;
    white-space: pre-wrap;
  }

  .author-info {
    margin-top: 1rem;
  }

  .message-list {
    margin-top: 1rem;
  }
}
</style>
